#include "fase.h"
#include <QDebug>

Fase::Fase():
    _elementosDeFase(new QHash<PontoHash, editacao::Elementos>)
{
}

Fase::Fase(QImage &imagemFase, int totalPontoX):
    _imagemFase(imagemFase),
    _elementosDeFase(new QHash<PontoHash,  editacao::Elementos>),
    _totalPontoX(totalPontoX)
{
}

Fase::Fase(QImage &imagemFase, QHash<PontoHash,  editacao::Elementos> *elementosDeFase, int totalPontoX):
    _imagemFase(imagemFase),
    _elementosDeFase(elementosDeFase),
    _totalPontoX(totalPontoX)
{
}

Fase::~Fase()
{
    delete this->_elementosDeFase;
}

QImage Fase::imagemFase()const
{
    return this->_imagemFase;
}

QHash<PontoHash, editacao::Elementos> *Fase::elementosDeFase()const
{
    return this->_elementosDeFase;
}

QPoint Fase::pontoPartida()const
{
    return this->_pontoPartida;
}

int Fase::totalPontoX()const
{
    return this->_totalPontoX;
}
void Fase::setImagemFase(QImage &imagemFase)
{
    this->_imagemFase = imagemFase;
}

void Fase::setElementoDeFase(QHash<PontoHash, editacao::Elementos> &elementosDeFase)
{
    *this->_elementosDeFase = elementosDeFase;
}

void Fase::setPontoPartida(QPoint &pontoPartida)
{
    this->_pontoPartida = pontoPartida;
}

void Fase::setTotalPontoX(int totalPontoX)
{
    this->_totalPontoX = totalPontoX;
}

bool Fase::contemElemento(QPoint &ponto)
{
    PontoHash pontoHash(ponto);
    return this->_elementosDeFase->contains(pontoHash);
}

editacao::Elementos Fase::elemento(QPoint &ponto)
{
    PontoHash pontoHash(ponto);
    return this->_elementosDeFase->value(pontoHash);
}

void Fase::insereElemento(QPoint &ponto, editacao::Elementos elemento)
{
    PontoHash pontoHash(ponto);
    this->_elementosDeFase->insert(pontoHash, elemento);
}

void Fase::insereCaixaEmPontoX(QPoint &ponto)
{
    PontoHash pontoHash(ponto);
    this->_elementosDeFase->insertMulti(pontoHash, editacao::CAIXA);
}

void Fase::removeElemento(QPoint &ponto)
{
    PontoHash pontoHash(ponto);
    this->_elementosDeFase->remove(pontoHash);
}

editacao::Elementos Fase::tiraElemento(QPoint &ponto)
{
    PontoHash pontoHash(ponto);
    return this->_elementosDeFase->take(pontoHash);
}

const QHash<PontoHash, quint32> *Fase::converteHash(const QHash<PontoHash, editacao::Elementos> *elementosDeFase)
{
    QHash<PontoHash, quint32> *elemento32 = new QHash<PontoHash, quint32>;

    QHash<PontoHash, editacao::Elementos>::const_iterator iterador;
    for(iterador = elementosDeFase->begin(); iterador != elementosDeFase->end(); ++iterador)
    {
        elemento32->insert(iterador.key(), (quint32) iterador.value());
    }

    return elemento32;
}

QHash<PontoHash, editacao::Elementos> *Fase::desconverteHash(QHash<PontoHash, quint32> &elementosDeFase32)
{
    QHash<PontoHash, editacao::Elementos> *elementosDeFase = new QHash<PontoHash, editacao::Elementos>();

    QHash<PontoHash, quint32>::const_iterator iterador;
    editacao::Elementos valor;
    for(iterador = elementosDeFase32.begin(); iterador != elementosDeFase32.end(); ++iterador)
    {
        valor = editacao::NONE;
        switch(iterador.value())
        {
            case editacao::CAIXA:
                valor = editacao::CAIXA;
                break;
            case editacao::HEROI:
                valor = editacao::HEROI;
                break;
            case editacao::PAREDE:
                valor = editacao::PAREDE;
                break;
            case editacao::PONTOX:
                valor = editacao::PONTOX;
                break;
            default:
                break;
        }

        elementosDeFase->insert(iterador.key(), valor);
    }

    return elementosDeFase;
}

QDataStream &operator <<(QDataStream &stream, const Fase &fase)
{
    const QImage imagemFase = fase.imagemFase();
    const QHash<PontoHash, quint32> *elementosDeFase32 = Fase::converteHash(fase.elementosDeFase());
    const QPoint pontoPartida = fase.pontoPartida();
    const quint32 totalPontoX = (quint32) fase.totalPontoX();

    stream << totalPontoX;

    stream << pontoPartida;

    stream << imagemFase;

    stream << *elementosDeFase32;

    delete elementosDeFase32;

    return stream;
}

QDataStream &operator >>(QDataStream &stream, Fase &fase)
{
    QImage imagemFase;
    QHash<PontoHash, quint32> elementosDeFase32;
    QPoint pontoPartida;
    quint32 totalPontoX;

    qDebug() << ">> totalPontoX vai comecar\n";
    stream >> totalPontoX;
    qDebug() << ">> totalPontoX terminou\n";

    qDebug() << ">> pontoPartida vai comecar\n";
    stream >> pontoPartida;
    qDebug() << ">> pontoPartida terminou\n";

    qDebug() << ">> imagemFase vai comecar\n";
    stream >> imagemFase;
    qDebug() << ">> imagemFase terminou\n";

    qDebug() << ">> elementosDeFase vai comecar\n";
    stream >> elementosDeFase32;
    qDebug() << ">> elementosDeFase terminou\n";

    fase.setTotalPontoX((int) totalPontoX);
    fase.setPontoPartida(pontoPartida);
    fase.setImagemFase(imagemFase);
    fase.setElementoDeFase(*(Fase::desconverteHash(elementosDeFase32)));

    return stream;

}
